#include <atomic>
#include <thread>
#include <iostream>
#include <vector>

// ⾃旋锁（SpinLock）是⼀种忙等待的锁机制，适⽤于锁持有时间⾮常短的场景。
// 在多线程编程中，当⼀个线程尝试获取已被其他线程持有的锁时，⾃旋锁会让该
// 线程在循环中不断检查锁是否可⽤，⽽不是进⼊睡眠状态。这种⽅式可以减少上
// 下⽂切换的开销，但在锁竞争激烈或锁持有时间较⻓的情况下，会导致CPU资源的浪费。
// 以下是使⽤C++11实现的⼀个简单⾃旋锁⽰例：
class SpinLock
{
private:
	// ATOMIC_FLAG_INIT默认初始化为false
	std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
	void lock()
	{
		// test_and_set将内部值设置为true，并且返回之前的值
		// 第⼀个进来的线程将值原⼦的设置为true，返回false
		// 后⾯进来的线程将原⼦的值设置为true，返回true，所以卡在这⾥空转，
		// 直到第⼀个进去的线程unlock，clear，将值设置为false
		while (flag.test_and_set(std::memory_order_acquire));   // 读改写
	}

	void unlock()
	{
		// clear将值原⼦的设置为false
		flag.clear(std::memory_order_release);                  // 写
	}
};

// 测试⾃旋锁
void worker(SpinLock& lock, int& sharedValue) {
	lock.lock();

	// 模拟⼀些⼯作
	for (int i = 0; i < 1000000; ++i) {
		++sharedValue;
	}

	lock.unlock();
}

int main() 
{
	SpinLock lock;
	int sharedValue = 0;
	std::vector<std::thread> threads;

	// 创建多个线程
	for (int i = 0; i < 4; ++i) {
		threads.emplace_back(worker, std::ref(lock), std::ref(sharedValue));
	}

	// 等待所有线程完成
	for (auto& thread : threads) {
		thread.join();
	}
	std::cout << "Final shared value: " << sharedValue << std::endl;

	return 0;
}
